package com.khyr.config;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.khyr.entity.HisPatient;
import com.khyr.feign.UserFeign;
import com.khyr.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Configuration
public class SecurityConfig {
    @Autowired
    private UserFeign userFeign;

    //密码加密器
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    //规则
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //表单登录
        http.formLogin(form -> form
                .loginProcessingUrl("/login") //登录请求的处理路径
                .successHandler(succussHandler()) // 登录成功的处理器
                .failureHandler(failHandler())
                .permitAll()
        );

        http.authorizeHttpRequests().anyRequest().authenticated();

        http.csrf(csrf -> csrf.disable());
        http.exceptionHandling(c->c.accessDeniedHandler(accessDenieHandler()));
        return http.build();
    }

    private AccessDeniedHandler accessDenieHandler() {
        return (request, response, accessDeniedException) -> {
            //权限不足后的业务。
            response.setContentType("application/json;charset=utf-8");
            //返回json数据.
            R r=new R(403,"权限不足",null);
            String jsonString = JSON.toJSONString(r);
                //获取输出对象
            PrintWriter out = response.getWriter();
            out.println(jsonString);
            //刷新输出对象
            out.flush();
            //关闭输出对象
            out.close();
        };
    }

    private AuthenticationFailureHandler failHandler() {
        return (request, response, exception) -> {
            //登录失败后的业务。
            response.setContentType("application/json;charset=utf-8");
            System.out.println("登录失败");
            //返回json数据.
            R r=new R(500,"登录失败",null);
            String jsonString = JSON.toJSONString(r);
                //获取输出对象
            PrintWriter out = response.getWriter();
            out.println(jsonString);
            //刷新输出对象
            out.flush();
            //关闭输出对象
            out.close();
        };
    }

    @Autowired
    private RedisTemplate redisTemplate;
    private AuthenticationSuccessHandler succussHandler() {
        return (request, response, authentication) -> {
            System.out.println("登录成功");
            //登录成功后的业务。
            //1.生成uuid
            String token = UUID.randomUUID().toString().replace("-","");
            //2.以token为key，用户信息为value，保存到redis中
            //用户名和权限
            Object name = authentication.getName();
            Object username = authentication.getName();
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            List<String> permissions=new ArrayList<>();
            for(GrantedAuthority a:authorities){
                permissions.add(a.getAuthority());
            }
            redisTemplate.opsForHash().put("user::login::"+token,"name",name);
//            redisTemplate.opsForHash().put("user::login::"+token,"username",username);
            redisTemplate.opsForHash().put("user::login::"+token,"permessions",permissions);
            redisTemplate.expire("user::login::"+token,999, TimeUnit.DAYS);
            response.setContentType("application/json;charset=utf-8");
            //通过token拿到用户信息
            Object name1 = redisTemplate.opsForHash().get("user::login::" + token, "name");
//            QueryWrapper<HisPatient> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("phone", name1);
//            HisPatient hisPatient = hisPatientDao.selectOne(queryWrapper);

            R<HisPatient> r1= userFeign.getByName2((String) name1);
            r1.getData().setToken(token);
            //返回json数据.
            R r=new R(200,"登录成功",r1.getData());
            String jsonString = JSON.toJSONString(r);
                //获取输出对象
            PrintWriter out = response.getWriter();
            out.println(jsonString);
            //刷新输出对象
            out.flush();
            //关闭输出对象
            out.close();
        };
    }
}
